]> dgit.raspbian.org Git - gnome-shell.git/commitdiff
workspace: Use Util.lerp() instead of actor box for interpolating
authorJonas Dreßler <verdre@v0yd.nl>
Thu, 25 Feb 2021 16:20:42 +0000 (17:20 +0100)
committerMarge Bot <marge-bot@gnome.org>
Tue, 9 Mar 2021 15:40:49 +0000 (15:40 +0000)
Instead of interpolating our workspace and layout boxes for each child
using clutter_actor_box_interpolate(), use our Util.lerp() function and
stay in JS land instead.

This is quite a large performance improvement since it avoids
heap-allocating a new ClutterActorBox for every child. With this, we're
finally at a duration of 1.0 ms to allocate the Workspace with 20
windows.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1743>

js/ui/workspace.js

index f11f546f1e0393894466efb51321559214e3897a..1a5bd02271ace33036ab1f7e2cd44cb9fdacb066 100644 (file)
@@ -616,8 +616,7 @@ var WorkspaceLayout = GObject.registerClass({
 
         const allocationScale = containerBox.get_width() / workareaWidth;
 
-        const workspaceBox = new Clutter.ActorBox();
-        const layoutBox = new Clutter.ActorBox();
+        const childBox = new Clutter.ActorBox();
 
         const { ControlsState } = OverviewControls;
         const inSessionTransition =
@@ -625,44 +624,46 @@ var WorkspaceLayout = GObject.registerClass({
 
         const nSlots = this._windowSlots.length;
         for (let i = 0; i < nSlots; i++) {
-            const [x, y, width, height, child] = this._windowSlots[i];
+            let [x, y, width, height, child] = this._windowSlots[i];
             if (!child.visible)
                 continue;
 
             const windowInfo = this._windows.get(child);
 
+            let workspaceBoxX, workspaceBoxY;
+            let workspaceBoxWidth, workspaceBoxHeight;
+
             if (windowInfo.metaWindow.showing_on_its_workspace()) {
-                workspaceBox.set_origin(
-                    child.boundingBox.x - workareaX,
-                    child.boundingBox.y - workareaY);
-                workspaceBox.set_size(
-                    child.boundingBox.width,
-                    child.boundingBox.height);
+                workspaceBoxX = (child.boundingBox.x - workareaX) * allocationScale;
+                workspaceBoxY = (child.boundingBox.y - workareaY) * allocationScale;
+                workspaceBoxWidth = child.boundingBox.width * allocationScale;
+                workspaceBoxHeight = child.boundingBox.height * allocationScale;
             } else {
-                workspaceBox.set_origin(workareaX, workareaY);
-                workspaceBox.set_size(0, 0);
+                workspaceBoxX = workareaX * allocationScale;
+                workspaceBoxY = workareaY * allocationScale;
+                workspaceBoxWidth = 0;
+                workspaceBoxHeight = 0;
 
                 child.opacity = stateAdjustementValue * 255;
             }
 
-            workspaceBox.scale(allocationScale);
-
             // Don't allow the scaled floating size to drop below
             // the target layout size.
             // We only want to apply this when the scaled floating size is
             // actually larger than the target layout size, that is while
             // animating between the session and the window picker.
             if (inSessionTransition) {
-                workspaceBox.set_size(
-                    Math.max(workspaceBox.get_width(), width),
-                    Math.max(workspaceBox.get_height(), height));
+                workspaceBoxWidth = Math.max(workspaceBoxWidth, width);
+                workspaceBoxHeight = Math.max(workspaceBoxHeight, height);
             }
 
-            layoutBox.set_origin(x, y);
-            layoutBox.set_size(width, height);
+            x = Util.lerp(workspaceBoxX, x, stateAdjustementValue);
+            y = Util.lerp(workspaceBoxY, y, stateAdjustementValue);
+            width = Util.lerp(workspaceBoxWidth, width, stateAdjustementValue);
+            height = Util.lerp(workspaceBoxHeight, height, stateAdjustementValue);
 
-            const childBox = workspaceBox.interpolate(layoutBox,
-                stateAdjustementValue);
+            childBox.set_origin(x, y);
+            childBox.set_size(width, height);
 
             if (windowInfo.currentTransition) {
                 windowInfo.currentTransition.get_interval().set_final(childBox);